package com.plian.system.service.im.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.read.listener.PageReadListener;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.plian.Tools.*;
import com.plian.Tools.pagedata.PageData;
import com.plian.spring.SpringUtil;
import com.plian.system.bean.im.ProjectInfoImportExcelBean;
import com.plian.system.common.status.CheckStatus;
import com.plian.system.constant.baseinfo.ValueSetConstant;
import com.plian.system.constant.sys.FormStatusConstant;
import com.plian.system.constant.sys.FormTypeConstant;
import com.plian.system.constant.yth.YthConstant;
import com.plian.system.dao.sys.orgzation.OrgzationDao;
import com.plian.system.dao.sys.user.UserDao;
import com.plian.system.entity.fr.enterprise.Enterprise;
import com.plian.system.entity.im.BaseInvestmentPlan;
import com.plian.system.entity.im.FixedInvestmentPlan;
import com.plian.system.entity.im.ProjectInfo;
import com.plian.system.entity.im.StakeInvestmentPlan;
import com.plian.system.entity.sys.*;
import com.plian.system.excel.ImportExcelUtil;
import com.plian.system.excel.ImportResult;
import com.plian.system.mapper.im.ExecutionProjectSituationMapper;
import com.plian.system.mapper.im.ProjectInfoMapper;
import com.plian.system.model.CommonCode;
import com.plian.system.model.R;
import com.plian.system.mybatis.base.BaseFlowService;
import com.plian.system.mybatis.base.BaseServiceImpl;
import com.plian.system.properties.GzwProperties;
import com.plian.system.service.bt.baseinfo.BaseInfoService;
import com.plian.system.service.fr.enterprise.IEnterpriseService;
import com.plian.system.service.im.IBaseInvestmentPlanService;
import com.plian.system.service.im.IFixedInvestmentPlanService;
import com.plian.system.service.im.IProjectInfoService;
import com.plian.system.service.im.IStakeInvestmentPlanService;
import com.plian.system.service.sys.file.FileService;
import com.plian.system.service.sys.message.IMessageService;
import com.plian.system.service.sys.office.IOfficeService;
import com.plian.system.service.sys.orgzation.IOrgService;
import com.plian.system.service.sys.orgzation.OrgzationService;
import com.plian.system.service.sys.region.IRegionService;
import com.plian.system.service.sys.system.IFormHistoryRecordService;
import com.plian.system.vo.im.ExecutionProjectSituationVO;
import com.plian.system.vo.im.ProjectInfoVO;
import com.plian.system.vo.yth.YthResult;
import com.plian.system.wrapper.im.ProjectInfoWrapper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.env.Environment;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.Future;
import java.util.stream.Collectors;

import static com.plian.system.constant.sys.FormStatusConstant.UNREVIEWED;
import static com.plian.system.constant.sys.FormTypeConstant.PROJECT_INFO;

/**
 * 服务实现类
 *
 * @author
 * @since 2019-09-27
 */
@Slf4j
@Service
@AllArgsConstructor
public class ProjectInfoServiceImpl extends BaseServiceImpl<ProjectInfoMapper, ProjectInfo> implements IProjectInfoService, BaseFlowService {

	private OrgzationDao orgzationDao;

	private BaseInfoService baseInfoService;

	private IFixedInvestmentPlanService fixedInvestmentPlanService;

	private IStakeInvestmentPlanService stakeInvestmentPlanService;

	private ExecutionProjectSituationMapper executionProjectSituationMapper;

	private ProjectInfoWrapper projectInfosWrapper;
	private ProjectInfoMapper projectInfoMapper;

	private FileService fileService;

	private IOrgService orgService;

	private IEnterpriseService enterpriseService;

	private IFormHistoryRecordService formHistoryRecordService;

	private UserDao userDao;

	private IMessageService messageService;

	private IOfficeService officeService;

	private GzwProperties gzwProperties;

	private OrgzationService orgzationService;
	private Environment environment;

	private final IRegionService regionService;

	private static Map<String, String> fileNameMap = new HashMap<>();
	@Override
	@Transactional(rollbackFor=RuntimeException.class)
	public boolean saveOrUpdate(ProjectInfo projectInfo) {
		boolean flag = false;
		if (!Optional.ofNullable(projectInfo.getId()).isPresent()) {
			flag = true;
		}
		if (projectInfo.getFormType() == null){
			projectInfo.setFormType(String.valueOf(PROJECT_INFO));
		}
		if (StringUtil.isBlank(projectInfo.getOrderNumber())){
			projectInfo.setOrderNumber("9999");
		}
		boolean result = super.saveOrUpdate(projectInfo);
		if (flag){
			fileService.saveAll(String.valueOf(projectInfo.getId()), projectInfo.getDocList());
		}else {
			fileService.edit(String.valueOf(projectInfo.getId()), projectInfo.getDocList());
		}
		return result;
	}

	@Override
	@Transactional(rollbackFor=RuntimeException.class)
	public boolean deleteLogic(List<Long> ids) {
		for (Long id : ids) {
			ProjectInfo projectInfo = getById(id);
			if (projectInfo == null) {
				return false;
			}
		}
		return super.deleteLogic(ids);
	}

	@Override
	@Async("ttlExecutor")
	public Future<ImportResult> importExcel(String progressId, InputStream inputStream) {
		String progress = "progress";
		String key = progressId + "#half:hour";
		String orgId = TokenUtil.getTokenOrgId();

		try {
			byte[] bytes = IOUtils.toByteArray(inputStream);
			InputStream stream = new ByteArrayInputStream(bytes);

			Map<String, Map<String, String>> mapRef = getRef();

			//谋划
            List<Object> projectList = new ArrayList<>();
			//新建
            List<Object> projectPlanList = new ArrayList<>();


			EasyExcel.read(stream).build()
					.read(EasyExcel.readSheet(1).headRowNumber(1).head(ProjectInfoImportExcelBean.class)
							.registerReadListener(new PageReadListener<>(list -> projectPlanList.addAll(list))).build());

			ImportExcelUtil.filterEmpty(projectPlanList);
			ImportResult result = checkData(mapRef, progressId,projectPlanList);


			if (!result.isSuccess()){
				CacheUtil.put(progress, progress, key, result.getMsg());
				return new AsyncResult<>(result);
			}

			int count = 0;
			int size = projectList.size() + projectPlanList.size();


			for (Object readExcel : projectPlanList) {
				ProjectInfo projectInfo = (ProjectInfo) ImportExcelUtil.getEntityByExcelBean((ProjectInfoImportExcelBean)readExcel,new ProjectInfo());
				LambdaQueryWrapper<ProjectInfo> queryWrapper = new LambdaQueryWrapper<>();
				queryWrapper.eq(ProjectInfo::getCreateCompanyId, orgId);
				queryWrapper.eq(ProjectInfo::getProjectName, projectInfo.getProjectName());
				ProjectInfo old = getOne(queryWrapper);
				if (Optional.ofNullable(old).isPresent()){
					projectInfo.setId(old.getId());
				}
				Optional.ofNullable(orgService.getOne(Wrappers.<Org>lambdaQuery().eq(Org::getName, projectInfo.getInvestmentCompanyId()))).ifPresent( org ->{
					PageData pageData = new PageData();
					pageData.put("orgId",org.getId());
					PageData resultPd = orgzationService.getGroupbyId(pageData).getPageData();
					projectInfo.setSubordinateGroupId(resultPd.getString("id"));
				});
				projectInfo.setFillingUnitId(orgId);
				projectInfo.setWarehousingDate(new Date());

				//入库
				try {
					submit(projectInfo);
					count++;
					int value = count * 100 / size;
					CacheUtil.put(progress, progress, key, value+100);
				} catch (Exception e) {
					log.error("导入失败：{}",e.getMessage());
					e.getStackTrace();
					CacheUtil.put(progress, progress, key,"导入失败："+e.getMessage());
					return new AsyncResult<>(new ImportResult(false,projectInfo + "导入失败"));
				}
			}

		}catch (Exception e) {
			log.error(ExceptionUtils.getFullStackTrace(e));
			log.error("解析失败");
			CacheUtil.put(progress, progress, key,"解析失败");
			return new AsyncResult<>(new ImportResult(false,"解析失败"));
		}

		CacheUtil.put(progress, progress, key,"导入成功");
		return new AsyncResult<>(new ImportResult(true,"导入成功"));
	}

	/**
	 * @Description: //TODO 接收数字宁波-项目信息
	 * @Author: Take-off
	 * @Date: 2:40 PM 2023/2/28
	 * @Param: [data]
	 * @return: java.lang.String
	 **/
	@Override
	@Transactional(rollbackFor = RuntimeException.class)
	public String saveProjectInfos(String data){
		YthResult ythResult = new YthResult();
		//成功的id集合
		List<String> successIds = new ArrayList<>();
		//失败的id集合
		List<String> failIds = new ArrayList<>();
		//失败的原因
		List<String> failReasons = new ArrayList<>();
		//将json字符串转换成list
		List<ProjectInfo> projectInfos = JSON.parseArray(data, ProjectInfo.class);
		//判断list是否为空
		if (CollectionUtil.isNotEmpty(projectInfos)){
			//组织map
			Map<String, String> orgSourceMap = orgService.getSourceId();
			//根据datasourceIds 查询出所有的数据
			List<ProjectInfo> list = list(new LambdaQueryWrapper<ProjectInfo>().in(ProjectInfo::getDataSourceId, projectInfos.stream().map(ProjectInfo::getDataSourceId).toArray()));
			//如果数据库中有数据，就更新，没有就新增
			for (ProjectInfo projectInfo:projectInfos) {
				String dataSourceId = projectInfo.getDataSourceId();
				transfer(projectInfo,orgSourceMap);
				if (CollectionUtil.isNotEmpty(list)){
					List<String> olIds = list.stream().map(ProjectInfo::getDataSourceId).collect(Collectors.toList());
					//判断数据库中是否有数据
					if (olIds.contains(dataSourceId)){
						for (ProjectInfo oldEntity:list) {
							if (dataSourceId.equals(oldEntity.getDataSourceId())) {
								//判断status是否为0，如果是0，就更新，不是0，就不更新
								if (CheckStatus.checkCode(oldEntity.getStatus())){
									successIds.add(dataSourceId);
									projectInfo.setId(oldEntity.getId());
									projectInfo.setDataSource(YthConstant.DATA_NINGBO);
									submit(projectInfo);
									list.remove(oldEntity);
									break;
								}else {
									failIds.add(dataSourceId);
									failReasons.add("dataSourceId:"+dataSourceId+"数据已提交且已经在流程中，无法更新");
									break;
								}
							}
						}
					}else {
						//如果数据库中没有数据，就新增
						projectInfo.setDataSource(YthConstant.DATA_NINGBO);
						submit(projectInfo);
						successIds.add(projectInfo.getDataSourceId());
					}
				}else {
					//如果数据库中没有数据，就新增
					projectInfo.setDataSource(YthConstant.DATA_NINGBO);
					submit(projectInfo);
					successIds.add(projectInfo.getDataSourceId());
				}
			}
		} else {
			failReasons.add("数据为空");
		}
		ythResult.setSuccessIds(successIds);
		ythResult.setFailIds(failIds);
		ythResult.setFailReason(StringUtils.join(failReasons, ";"));
		//ythResult转换成json字符串
		return JSON.toJSONString(ythResult);
	}

	private void transfer(ProjectInfo projectInfo,Map<String, String> orgSourceMap){

		Optional.ofNullable(projectInfo.getSubordinateGroupId()).ifPresent(m ->
				{
					String orgId = orgSourceMap.get(m);
					projectInfo.setSubordinateGroupId(orgId);
					projectInfo.setCreateCompanyId(orgId);
					projectInfo.setFillingUnitId(orgId);
				}
		);
	}

	@Override
	public String checkName(ProjectInfo projectInfo) {
		String name = "";
		if (StringUtil.isBlank(projectInfo.getProjectName())){
			return "项目名称为空";
		}
		//负面清单类型判断
		if (Optional.ofNullable(projectInfo.getInvestmentAttribute()).isPresent() && projectInfo.getInvestmentAttribute() == 3){
			//2境外
			if (Optional.ofNullable(projectInfo.getInvestmentRegion()).isPresent() && projectInfo.getInvestmentRegion() == 2){
				//项目地址非浙江省
				if (Optional.ofNullable(projectInfo.getProvinceCode()).isPresent() && !"33".equals(projectInfo.getProvinceCode())){
					//非上市公司
					if (Optional.ofNullable(projectInfo.getInvestmentCompanyId()).isPresent()){
						Org org = orgService.getOne(Wrappers.<Org>lambdaQuery().eq(Org::getName, projectInfo.getInvestmentCompanyId()));
						if (Optional.ofNullable(org).isPresent()){
							Enterprise enterprise = enterpriseService.findByOrgId(org.getId());
							if (Optional.ofNullable(enterprise.getIsListed()).isPresent() && enterprise.getIsListed() == 0 ){
								if (projectInfo.getIsNegativeProject() ==2){
									name = "项目应该为负面清单";
								}else {
									if (projectInfo.getIsNegativeProject() != 1){
										name = "项目负面清单类型应该为监管类";
									}
								}
							}
						}

					}
				}
			}
		}
		if (StringUtil.isNotBlank(name)){
			return name;
		}
		LambdaQueryWrapper<ProjectInfo> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(ProjectInfo::getCreateCompanyId, TokenUtil.getTokenOrgId());
		queryWrapper.eq(ProjectInfo::getProjectName, projectInfo.getProjectName());
		ProjectInfo old = getOne(queryWrapper);

		if (!Optional.ofNullable(old).isPresent()){
			return null;
		}else if (old.getId().equals(projectInfo.getId())){
			return null;
		}else {
			name = "该项目名称已存在";
		}

		return name;
	}

	@Override
	public void exportTemplateExcel(HttpServletResponse response, OutputStream os) {
		try {
			String fname = "项目信息导入模板";
			os = response.getOutputStream();//取得输出流
			response.reset();//清空输出流
			//下面是对中文文件名的处理
			response.setCharacterEncoding("UTF-8");//设置相应内容的编码格式
			InputStream inputStream = this.getClass().getResourceAsStream("/exceldemo/projectInfoImportNew.xlsx");
			fname = java.net.URLEncoder.encode(fname, "UTF-8");
			response.setHeader("Content-Disposition", "attachment;filename=" + new String(fname.getBytes("UTF-8"), "UTF-8") + ".xlsx");

			response.setContentType("application/msexcel");//定义输出类型
			int len;
			byte[] b = new byte[2048];
			while ((len = inputStream.read(b)) != -1) {
				os.write(b, 0, len);
			}
			response.setHeader("Content-Length", String.valueOf(inputStream.available()));

			inputStream.close();
			os.close();
		}catch (Exception e){
			log.error(ExceptionUtils.getFullStackTrace(e));
		}
	}

	@Override
	public void addOtherFiledForPlanExecution(List<ProjectInfoVO> projectInfoVOList,String fillingMonth) {
		QueryWrapper bQueryWrapper=new QueryWrapper();
		bQueryWrapper.eq("filing_year",fillingMonth.substring(0,4));
		bQueryWrapper.eq("create_company_id", TokenUtil.getTokenOrgId());
		bQueryWrapper.orderByDesc("filing_date");
		int month=Integer.parseInt(fillingMonth.substring(5,7))-1;
		String monthStr="";
		if(month<=9){
			monthStr="0"+month;
		}else{
			monthStr=month+"";
		}
		Map<String,String> map=new HashMap<>();
		map.put("startDate",fillingMonth.substring(0,4)+"-01");
		map.put("endDate",fillingMonth.substring(0,4)+"-"+monthStr);
		List<ExecutionProjectSituationVO>  executionProjectSituations=executionProjectSituationMapper.selectFullInfoList(map);
		Map<String,List<ExecutionProjectSituationVO>> projectMap=executionProjectSituations.stream().collect(Collectors.groupingBy(record->record.getProjectName()));
		IBaseInvestmentPlanService baseInvestmentPlanService=SpringUtil.getBean(IBaseInvestmentPlanService.class);
		List<BaseInvestmentPlan> baseInvestmentExecutions=baseInvestmentPlanService.list(bQueryWrapper);
		if(baseInvestmentExecutions.size()>0){
			Long baseId=null;
			//项目投资年度填报多次时取最新的一条
			if(baseInvestmentExecutions.size()>0){
				baseId=baseInvestmentExecutions.get(0).getId();
			}
			QueryWrapper queryWrapper=new QueryWrapper();
			queryWrapper.eq("base_investment_plan_id",baseId);
			List<FixedInvestmentPlan> fixedInvestmentPlans = fixedInvestmentPlanService.list(queryWrapper);
			List<StakeInvestmentPlan> stakeInvestmentPlans=stakeInvestmentPlanService.list(queryWrapper);
			Map<String, BigDecimal> fixedMap=fixedInvestmentPlans.stream().collect(Collectors.toMap(record->record.getProjectName(),record->record.getPlanInvestmentTotal()));
			Map<String, BigDecimal> stakeMap=stakeInvestmentPlans.stream().collect(Collectors.toMap(record->record.getProjectName(),record->record.getPlanCompleteInvestment()));
			for(ProjectInfoVO projectInfoVO:projectInfoVOList){
				int investmentCategory=projectInfoVO.getInvestmentCategory();
				String projectName=projectInfoVO.getProjectName();
				if(investmentCategory==1){
					if(stakeMap.containsKey(projectName)){
						projectInfoVO.setPlanTotalInvestment(stakeMap.get(projectName));
					}
				}else if(investmentCategory==2){
					if(fixedMap.containsKey(projectName)){
						projectInfoVO.setPlanTotalInvestment(fixedMap.get(projectName));
					}
				}
				if(projectMap.containsKey(projectName)){
					List<ExecutionProjectSituationVO> executionProjectSituationVOS=projectMap.get(projectName);
					BigDecimal shouldLastCompleteInvestment=executionProjectSituationVOS.stream().map(ExecutionProjectSituationVO::getCompleteInvestment).reduce(BigDecimal.ZERO,BigDecimal::add);
					projectInfoVO.setShouldLastCompleteInvestment(shouldLastCompleteInvestment);
				}
			}
		}
	}

	@Override
	public void addOtherFiledForBasePlan(List<ProjectInfoVO> projectInfoVOList, String fillingMonth) {
		int year=Integer.parseInt(fillingMonth.substring(0,4));
		String preYear=(year-1)+"";
		StringBuilder msg=new StringBuilder();
		Map<String,String> preMap=new HashMap<>();
		preMap.put("startDate",preYear+"-01");
		preMap.put("endDate",preYear+"-12");
		List<ExecutionProjectSituationVO> preYearProjectSituationVOS= executionProjectSituationMapper.selectFullInfoList(preMap);
		Map<String,String> beforeThisYearMap=new HashMap<>();
		beforeThisYearMap.put("endDate",preYear+"-12");
		List<ExecutionProjectSituationVO> beforeThisYearProjectSituationVOS= executionProjectSituationMapper.selectFullInfoList(beforeThisYearMap);
		Map<String,List<ExecutionProjectSituationVO>> preYearProjectMap=preYearProjectSituationVOS.stream().collect(Collectors.groupingBy(record->record.getProjectName()));
		Map<String,List<ExecutionProjectSituationVO>> beforeThisYearProjectMap=beforeThisYearProjectSituationVOS.stream().collect(Collectors.groupingBy(record->record.getProjectName()));
		for(ProjectInfoVO projectInfoVO:projectInfoVOList){
			String projectName=projectInfoVO.getProjectName();
			if(preYearProjectMap.containsKey(projectName)){
				List<ExecutionProjectSituationVO> projectList=preYearProjectMap.get(projectName);
				BigDecimal completeInvestment=projectList.stream().map(record->record.getCompleteInvestment()).reduce(BigDecimal.ZERO, BigDecimal::add);
				projectInfoVO.setShouldCompleteInvestmentLastYear(completeInvestment);
			}
			if(beforeThisYearProjectMap.containsKey(projectName)){
				List<ExecutionProjectSituationVO> projectList=beforeThisYearProjectMap.get(projectName);
				BigDecimal completeInvestment=projectList.stream().map(record->record.getCompleteInvestment()).reduce(BigDecimal.ZERO, BigDecimal::add);
				projectInfoVO.setShouldCommpleteInvestmentTotal(completeInvestment);
			}
		}
	}

	private Map<String,Map<String,String>> getRef() {
		Map<String, Map<String, String>> mapRefs = new HashMap<>(16);
		mapRefs.put("projectNatureRef",baseInfoService.getChildMap(ValueSetConstant.NEW_PROJECT_NATURE));
		mapRefs.put("enterpriseRankRef",baseInfoService.getChildMap(ValueSetConstant.ENTERPRISE_RANK));
		mapRefs.put("projectTypeRef",baseInfoService.getChildMap(ValueSetConstant.PROJECT_TYPE));
		mapRefs.put("fundSourceRef",baseInfoService.getChildMap(ValueSetConstant.FUND_SOURCE));

		Map<String,String> unitRef = new HashMap<>(16);
		try{
			List<PageData> allOrgs =  orgzationDao.list(null);
			if (CollectionUtil.isNotEmpty(allOrgs)){
				for (PageData pageData : allOrgs){
					unitRef.put((String)pageData.get("name"), (String)pageData.get("id"));
				}

			}
		}catch (Exception e){
			log.error(ExceptionUtils.getFullStackTrace(e));
		}
		mapRefs.put("unitRef",unitRef);


		return mapRefs;
	}

	private ImportResult checkData(Map<String, Map<String,String>> mapRef, String progressId,List<Object> readPlanExcels) {
		ImportResult importResult = new ImportResult(true,"");

		StringBuilder msg = new StringBuilder();
		int size =  readPlanExcels.size();
		int count = 0;
		if (CollectionUtil.isNotEmpty(readPlanExcels)) {
			for (Object readExcel : readPlanExcels) {
				ProjectInfoImportExcelBean excelBean = (ProjectInfoImportExcelBean) readExcel;
				int index = readPlanExcels.indexOf(readExcel);

				//判空
				msg.append(ImportExcelUtil.checkEmpty("1", "项目名称",
						excelBean.getProjectName(), index).getMsg());
				msg.append(ImportExcelUtil.checkEmpty("1", "年度",
						excelBean.getLastYear(), index).getMsg());
				msg.append(ImportExcelUtil.checkEmpty("1", "投资性质",
						excelBean.getInvestmentCategory(), index).getMsg());

				msg.append(ImportExcelUtil.checkEmpty("1", "投资主体",
						excelBean.getInvestmentCompanyId(), index).getMsg());

				msg.append(ImportExcelUtil.checkEmpty("1", "编号",
						excelBean.getProjectCode(), index).getMsg());

				msg.append(ImportExcelUtil.checkEmpty("1", "项目地点是否境内",
						excelBean.getInvestmentRegion(), index).getMsg());

				if(StringUtils.isNotBlank(excelBean.getInvestmentRegion())
						&& "1".equals(excelBean.getInvestmentRegion())){
					msg.append(ImportExcelUtil.checkEmpty("1", "邢台市域",
							excelBean.getIsLocal(), index).getMsg());
				}

				msg.append(ImportExcelUtil.checkEmpty("1", "项目具体地点（省编码）",
							excelBean.getProvinceCode(), index).getMsg());

				msg.append(ImportExcelUtil.checkEmpty("1", "项目具体地点（市编码）",
							excelBean.getCityCode(), index).getMsg());

				msg.append(ImportExcelUtil.checkEmpty("1", "项目具体地点（区、县编码）",
							excelBean.getAreaCode(), index).getMsg());

				msg.append(ImportExcelUtil.checkEmpty("1", "项目起始时间",
						excelBean.getAnticipateStartTime(), index).getMsg());

				msg.append(ImportExcelUtil.checkEmpty("1", "项目预计完成时间",
						excelBean.getPlanFinishDate(), index).getMsg());

				msg.append(ImportExcelUtil.checkEmpty("1", "项目阶段",
						excelBean.getProjectStatus(), index).getMsg());

				msg.append(ImportExcelUtil.checkEmpty("1", "是否为按本企业投资管理制度确定的重大投资项目",
						excelBean.getIsKeynoteProject(), index).getMsg());

				msg.append(ImportExcelUtil.checkEmpty("1", "是否为特别监管类投资项目",
						excelBean.getIsSpecialSupervise(), index).getMsg());

				msg.append(ImportExcelUtil.checkEmpty("1", "是否属于战新及分类代码和名称",
						excelBean.getIsZhanXin(), index).getMsg());

				msg.append(ImportExcelUtil.checkEmpty("1", "行业分类代码",
						excelBean.getIndustryCode(), index).getMsg());

				msg.append(ImportExcelUtil.checkEmpty("1", "国民经济行业名称",
						excelBean.getNationalEconomyName(), index).getMsg());

				msg.append(ImportExcelUtil.checkEmpty("1", "是否属于现代服务业及分类代码和名称",
						excelBean.getIsNowService(), index).getMsg());

				msg.append(ImportExcelUtil.checkEmpty("1", "是否主业投资",
						excelBean.getIsMainBusiness(), index).getMsg());

				if(StringUtils.isNotBlank(excelBean.getIsMainBusiness())
						&& "2".equals(excelBean.getIsMainBusiness())){
					msg.append(ImportExcelUtil.checkEmpty("1", "主业名称",
							excelBean.getMainBusinessName(), index).getMsg());
				}

				msg.append(ImportExcelUtil.checkEmpty("1", "项目内容",
						excelBean.getProjectIntroduction(), index).getMsg());

				if(StringUtils.isNotBlank(excelBean.getInvestmentCategory()) && "2".equals(excelBean.getInvestmentCategory())){
					msg.append(ImportExcelUtil.checkEmpty("1", "是否于该年一季度开工建设",
							excelBean.getIsLastYearFirstQuarter(), index).getMsg());
					msg.append(ImportExcelUtil.checkEmpty("1", "是否为该年省重点建设项目",
							excelBean.getIsLastProvinceKeynote(), index).getMsg());
					msg.append(ImportExcelUtil.checkEmpty("1", "是否为该年市重点建设项目",
							excelBean.getIsLastCityKeynote(), index).getMsg());
				}

				msg.append(ImportExcelUtil.checkEmpty("1", "项目总投资额",
						excelBean.getPlanInvestment(), index).getMsg());

				msg.append(ImportExcelUtil.checkEmpty("1", "项目总投资-自有资金",
						excelBean.getCompanyPlanInvestment(), index).getMsg());

				msg.append(ImportExcelUtil.checkEmpty("1", "项目总投资-贷款",
						excelBean.getInvestmentLoanAmount(), index).getMsg());

				msg.append(ImportExcelUtil.checkEmpty("1", "项目总投资-其他",
						excelBean.getInvestmentOtherAmount(), index).getMsg());

				msg.append(ImportExcelUtil.checkEmpty("1", "本年度计划投资额",
						excelBean.getThisYearPlanAmount(), index).getMsg());

				msg.append(ImportExcelUtil.checkEmpty("1", "本年度计划投资-自有资金",
						excelBean.getThisYearOwnAmount(), index).getMsg());

				msg.append(ImportExcelUtil.checkEmpty("1", "本年度计划投资-贷款",
						excelBean.getThisYearLoanAmount(), index).getMsg());

				msg.append(ImportExcelUtil.checkEmpty("1", "本年度计划投资-其他",
						excelBean.getThisYearOtherAmount(), index).getMsg());

				msg.append(ImportExcelUtil.checkEmpty("1", "截至去年年底完成投资额",
						excelBean.getLastYearFinishAmount(), index).getMsg());

				msg.append(ImportExcelUtil.checkEmpty("1", "投资完成后所占股比",
						excelBean.getFinishShare(), index).getMsg());

				msg.append(ImportExcelUtil.checkEmpty("1", "其他股东及股比情况",
						excelBean.getOtherShareholderShare(), index).getMsg());

				msg.append(ImportExcelUtil.checkEmpty("1", "预计投资收益率",
						excelBean.getPlanReturnRate(), index).getMsg());
			}
			//判断完空若有错直接返回
			if (msg.toString().length() > 0) {
				return new ImportResult(false, msg.toString());
			}

			for (Object readExcel : readPlanExcels) {
				ProjectInfoImportExcelBean excelBean = (ProjectInfoImportExcelBean) readExcel;
				int index = readPlanExcels.indexOf(readExcel);

				// 类型判断
				msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_INTEGER, "1", "投资性质",
						excelBean.getInvestmentCategory(), index).getMsg());
				msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_INTEGER, "1", "项目地点是否境内",
						excelBean.getInvestmentRegion(), index).getMsg());
				if(StringUtils.isNotBlank(excelBean.getInvestmentRegion())
						&& "1".equals(excelBean.getInvestmentRegion())){
					msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_INTEGER, "1", "邢台市域",
							excelBean.getIsLocal(), index).getMsg());
				}

				msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_DATE, "1", "项目起始时间",
						excelBean.getAnticipateStartTime(), index).getMsg());
				msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_DATE, "1", "项目预计完成时间",
						excelBean.getPlanFinishDate(), index).getMsg());

				msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_INTEGER, "1", "项目状态",
						excelBean.getProjectStatus(), index).getMsg());

				msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_INTEGER, "1", "是否为按本企业投资管理制度确定的重大投资项目",
						excelBean.getIsKeynoteProject(), index).getMsg());
				msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_INTEGER, "1", "是否为特别监管类投资项目",
						excelBean.getIsSpecialSupervise(), index).getMsg());
				msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_INTEGER, "1", "是否主业投资",
						excelBean.getIsMainBusiness(), index).getMsg());
				if(StringUtils.isNotBlank(excelBean.getInvestmentCategory()) && "2".equals(excelBean.getInvestmentCategory())){
					msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_INTEGER,"1", "是否于该年一季度开工建设",
							excelBean.getIsLastYearFirstQuarter(), index).getMsg());
					msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_INTEGER,"1", "是否为该年省重点建设项目",
							excelBean.getIsLastProvinceKeynote(), index).getMsg());
					msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_INTEGER,"1", "是否为该年市重点建设项目",
							excelBean.getIsLastCityKeynote(), index).getMsg());
				}
				msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_BIGDECIMAL,"1", "项目总投资额",
						excelBean.getPlanInvestment(), index).getMsg());

				msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_BIGDECIMAL,"1", "项目总投资-自有资金",
						excelBean.getCompanyPlanInvestment(), index).getMsg());

				msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_BIGDECIMAL,"1", "项目总投资-贷款",
						excelBean.getInvestmentLoanAmount(), index).getMsg());

				msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_BIGDECIMAL,"1", "项目总投资-其他",
						excelBean.getInvestmentOtherAmount(), index).getMsg());

				msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_BIGDECIMAL,"1", "本年度计划投资额",
						excelBean.getThisYearPlanAmount(), index).getMsg());

				msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_BIGDECIMAL,"1", "本年度计划投资-自有资金",
						excelBean.getThisYearOwnAmount(), index).getMsg());

				msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_BIGDECIMAL,"1", "本年度计划投资-贷款",
						excelBean.getThisYearLoanAmount(), index).getMsg());

				msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_BIGDECIMAL,"1", "本年度计划投资-其他",
						excelBean.getThisYearOtherAmount(), index).getMsg());

				msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_BIGDECIMAL,"1", "截至去年年底完成投资额",
						excelBean.getLastYearFinishAmount(), index).getMsg());

				msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_BIGDECIMAL,"1", "投资完成后所占股比",
						excelBean.getFinishShare(), index).getMsg());

				msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_BIGDECIMAL,"1", "其他股东及股比情况",
						excelBean.getOtherShareholderShare(), index).getMsg());

				msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_BIGDECIMAL,"1", "预计投资收益率",
						excelBean.getPlanReturnRate(), index).getMsg());
			}
			//判断完类型若有错直接返回
			if (msg.toString().length() > 0) {
				return new ImportResult(false, msg.toString());
			}

			//对象和字典是否存在校验
			for (Object readExcel : readPlanExcels) {
				ProjectInfoImportExcelBean excelBean = (ProjectInfoImportExcelBean) readExcel;
				int index = readPlanExcels.indexOf(readExcel);
				index += 2;
				//对象和字典是否存在校验
				//单位名称

				if (!StringUtil.isEmpty(excelBean.getInvestmentCategory())) {
					if (!("1".equals(excelBean.getInvestmentCategory()) || "2".equals(excelBean.getInvestmentCategory())||"3".equals(excelBean.getInvestmentCategory()) || "4".equals(excelBean.getInvestmentCategory()))) {
						msg.append("sheet1第" + index + "行(投资性质=" + excelBean.getInvestmentCategory() + ")错误\n");
					}
				}

				if (!StringUtil.isEmpty(excelBean.getInvestmentRegion())) {
					if (!("1".equals(excelBean.getInvestmentRegion()) || "2".equals(excelBean.getInvestmentRegion()))) {
						msg.append("sheet1第" + index + "行(项目地点是否境内=" + excelBean.getInvestmentRegion() + ")错误\n");
					}
				}
				if (!StringUtil.isEmpty(excelBean.getIsLocal())) {
					if (!("1".equals(excelBean.getIsLocal()) || "2".equals(excelBean.getIsLocal()))) {
						msg.append("sheet1第" + index + "行(邢台市域=" + excelBean.getIsLocal() + ")错误\n");
					}
				}

				//获取省市县 code比对
				Set<String> codeSet;
				List<String> codeList = new ArrayList<>();
				if(StringUtils.isNotBlank(excelBean.getProvinceCode())) codeList.add(excelBean.getProvinceCode());
				if(StringUtils.isNotBlank(excelBean.getCityCode()))codeList.add(excelBean.getCityCode());
				if(StringUtils.isNotBlank(excelBean.getAreaCode()))codeList.add(excelBean.getAreaCode());
				if(CollectionUtil.isEmpty(codeList)){
					codeSet = new HashSet<>();
				}else {
					List<Region> regionList = regionService.list(new LambdaQueryWrapper<Region>().in(Region::getCode, codeList));
					if(CollectionUtil.isEmpty(regionList)){
						codeSet = new HashSet<>();
					} else {
						codeSet = regionList.stream().map(Region::getCode).collect(Collectors.toSet());
					}
				}
				// 省编码校验
				if(!codeSet.contains(excelBean.getProvinceCode())) {
					msg.append(ImportExcelUtil.msgBuilder("1",String.valueOf(index),"项目具体地点（省编码）",
							excelBean.getProvinceCode(),"省编码不正确！"));
				}
				// 市编码校验
				if(!codeSet.contains(excelBean.getCityCode())) {
					msg.append(ImportExcelUtil.msgBuilder("1",String.valueOf(index),"项目具体地点（市编码）",
							excelBean.getCityCode(),"市编码不正确！"));
				}
				// 区县编码校验
				if(!codeSet.contains(excelBean.getAreaCode())) {
					msg.append(ImportExcelUtil.msgBuilder("1",String.valueOf(index),"项目具体地点（区、县编码）",
							excelBean.getAreaCode(),"区、县编码不正确！"));
				}

				//项目状态
				if (!StringUtil.isEmpty(excelBean.getProjectStatus())) {
					if (!("1".equals(excelBean.getProjectStatus()) || "2".equals(excelBean.getProjectStatus())|| "3".equals(excelBean.getProjectStatus()))) {
						msg.append("sheet1第" + index + "行(项目阶段=" + excelBean.getProjectStatus() + ")错误\n");
					}
				}
				if (!StringUtil.isEmpty(excelBean.getIsKeynoteProject())) {
					if (!("1".equals(excelBean.getIsKeynoteProject()) || "2".equals(excelBean.getIsKeynoteProject()))) {
						msg.append("sheet1第" + index + "行(是否为按本企业投资管理制度确定的重大投资项目=" + excelBean.getIsKeynoteProject() + ")错误\n");
					}
				}
				if (!StringUtil.isEmpty(excelBean.getIsSpecialSupervise())) {
					if (!("1".equals(excelBean.getIsSpecialSupervise()) || "2".equals(excelBean.getIsSpecialSupervise()))) {
						msg.append("sheet1第" + index + "行(是否为特别监管类投资项目=" + excelBean.getIsSpecialSupervise() + ")错误\n");
					}
				}
				if (!StringUtil.isEmpty(excelBean.getIsMainBusiness())) {
					if (!("1".equals(excelBean.getIsMainBusiness()) || "2".equals(excelBean.getIsMainBusiness()))) {
						msg.append("sheet1第" + index + "行(是否主业投资=" + excelBean.getIsMainBusiness() + ")错误\n");
					}
				}
				if(StringUtils.isNotBlank(excelBean.getInvestmentCategory()) && "2".equals(excelBean.getInvestmentCategory())){
					if (!StringUtil.isEmpty(excelBean.getIsLastYearFirstQuarter())) {
						if (!("1".equals(excelBean.getIsLastYearFirstQuarter()) || "2".equals(excelBean.getIsLastYearFirstQuarter()))) {
							msg.append("sheet1第" + index + "行(是否于该年一季度开工建设=" + excelBean.getIsLastYearFirstQuarter() + ")错误\n");
						}
					}
					if (!StringUtil.isEmpty(excelBean.getIsLastProvinceKeynote())) {
						if (!("1".equals(excelBean.getIsLastProvinceKeynote()) || "2".equals(excelBean.getIsLastProvinceKeynote()))) {
							msg.append("sheet1第" + index + "行(是否为该年省重点建设项目=" + excelBean.getIsLastProvinceKeynote() + ")错误\n");
						}
					}
					if (!StringUtil.isEmpty(excelBean.getIsLastCityKeynote())) {
						if (!("1".equals(excelBean.getIsLastCityKeynote()) || "2".equals(excelBean.getIsLastCityKeynote()))) {
							msg.append("sheet1第" + index + "行(是否为该年市重点建设项目=" + excelBean.getIsLastCityKeynote() + ")错误\n");
						}
					}
				}

				//投资企业
				if (StringUtil.isNotBlank(excelBean.getInvestmentCompanyId())) {
					Org org=orgService.getOne(Wrappers.<Org>lambdaQuery().eq(Org::getName, excelBean.getInvestmentCompanyId()));
					if(!(org!=null&&StringUtil.isNotBlank(org.getName()))){
						msg.append("sheet1第" + index + "行(投资主体=" + excelBean.getInvestmentCompanyId() + ")在系统单位列表中不存在\n");
					}
				}
				count++;
				int value = count * 100 / size;
				CacheUtil.put("progress","progress",progressId, value);
			}
		}

		//统一放置报错
		if (msg.toString().length()>0) {
			importResult = new ImportResult(false, msg.toString());
		}
		return importResult;

	}

	@Override
	public Map<String, Long> getSourceId(){
		List<ProjectInfo> projectInfos = list(new LambdaQueryWrapper<ProjectInfo>().eq(ProjectInfo::getDataSource, 3));
		return projectInfos.stream().collect(Collectors.toMap(ProjectInfo::getDataSourceId, ProjectInfo::getId));
	}

	@Override
	public HashMap<String,Object> commit(String id) {
		handleStatus(Long.valueOf(id), FormStatusConstant.FLOW);

		//将需要提交的流程变量返回，用于工作流侧
		return new HashMap<String,Object>();
	}

	@Override
	public Boolean finish(String id) {
		saveHistory(getById(id));
		return handleStatus(Long.valueOf(id), FormStatusConstant.FINISH);
	}

	@Override
	public Boolean reject(String id, int formState,String comment) {
		return handleStatus(Long.valueOf(id), formState);
	}

	@Override
	public List<PageData> findByIds(List<String> formIds) {
		LambdaQueryWrapper<ProjectInfo> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.in(ProjectInfo::getId, Func.toLongList(StringUtils.join(formIds, StringPool.COMMA)));
		List<ProjectInfo> projectInfos = list(queryWrapper);
		List<ProjectInfoVO> projectInfosVOS = projectInfosWrapper.entityToVO(projectInfos);
		List<PageData> pageDataList = new ArrayList<>();
		try{
			if (CollectionUtil.isNotEmpty(projectInfosVOS)){
				for (ProjectInfoVO vo : projectInfosVOS){
					PageData pd = new PageData();
					pd.put("id", vo.getId());
					pd.put("UNITNAME", vo.getFillingUnitName());
					pd.put("APPLICANTNAME", vo.getCreateUserName());
					pd.put("applicantId", vo.getCreateUser());
					pd.put("applyOrganizationId", vo.getFillingUnitId());
					pd.put("formType", PROJECT_INFO);
					pd.put("orgName", vo.getFillingUnitName());
					pageDataList.add(pd);
				}
			}

			return pageDataList;
		} catch (Exception e) {
			log.error(ExceptionUtils.getFullStackTrace(e));
		}
		return pageDataList;
	}

	@Override
	public List<Integer> getFormType() {
		return Arrays.asList(PROJECT_INFO);
	}

	@Override
	public void goBackToStash(String formId) {
		handleStatus(Long.valueOf(formId), UNREVIEWED);
	}

	private Boolean handleStatus(Long id, int updateStatus) {
		try {
			ProjectInfo projectInfo = getById(id);
			/**
			 * 设置审批人和审批时间
			 */
			if (updateStatus == FormStatusConstant.FINISH){
				projectInfo.setApprovedUser(TokenUtil.getTokenUserId());
				Date now = DateUtil.now();
				projectInfo.setApprovedTime(now);
			}
			projectInfo.setStatus(updateStatus);
			updateById(projectInfo);
			return true;
		} catch (Exception e) {
			log.error(ExceptionUtils.getFullStackTrace(e));
			return false;
		}
	}

	@Override
	public R<ProjectInfo> submit(ProjectInfo projectInfo) {
		if (Optional.ofNullable(projectInfo.getIsNegativeProject()).isPresent() &&  projectInfo.getIsNegativeProject() == 1){
			projectInfo.setNegativeType(null);
		}
		//默认可用
		if (!Optional.ofNullable(projectInfo.getIsAvailable()).isPresent()){
			projectInfo.setIsAvailable(2);
		}
		boolean result = saveOrUpdate(projectInfo);
		//谋划且不是负面清单项目 直接 保存历史记录，发送消息
		if ((Optional.ofNullable(projectInfo.getProjectStatus()).isPresent() && projectInfo.getProjectStatus() == 1
		&& Optional.ofNullable(projectInfo.getIsNegativeProject()).isPresent() &&  projectInfo.getIsNegativeProject() == 1) ||
				(Optional.ofNullable(projectInfo.getProjectStatus()).isPresent() && projectInfo.getProjectStatus() == 3)){
			projectInfo.setApprovedTime(new Date());
			saveHistory(projectInfo);
		}
		if (Optional.ofNullable(projectInfo.getStatus()).isPresent() && projectInfo.getStatus() ==3){
			projectInfo.setApprovedTime(new Date());
			saveHistory(projectInfo);
		}
		return result ? R.data(projectInfo) : new R(CommonCode.FAIL);
	}

	/**
	 * @Description: //TODO 保存历史记录，发送消息
	 * @Author: Take-off
	 * @Date: 4:04 PM 2023/4/27
	 * @Param: [projectInfo]
	 * @return: void
	 **/
	private void saveHistory(ProjectInfo projectInfo) {
		boolean sameFlag = true;
		ProjectInfo oldProject = new ProjectInfo();
		if (projectInfo.getId() != null) {
			oldProject = getById(projectInfo.getId());
			if (!projectInfo.equals(oldProject)) {
				sameFlag = false;
			}
		}
		if (Optional.ofNullable(projectInfo.getIsNegativeProject()).isPresent() && projectInfo.getIsNegativeProject() == 1) {
			projectInfo.setNegativeType(null);
		}

		if (!sameFlag) {
			ObjectMapper mapper = new ObjectMapper();
			try {
				ProjectInfoVO projectInfoVO = projectInfosWrapper.entityToVO(oldProject);
				setVO(projectInfoVO);
				formHistoryRecordService.submit(FormHistoryRecord.builder().formType(String.valueOf(FormTypeConstant.PROJECT_INFO))
						.record(mapper.writeValueAsString(projectInfoVO)).recordId(projectInfo.getId()).build());
			} catch (Exception e) {
				log.error("项目信息--> 历史数据版本保存失败");
			}
			//发消息给国资委
			sendMessage(projectInfo);
		}
	}

	/**
	 * @Description: //TODO 放置一些必要的key
	 * @Author: Take-off
	 * @Date: 4:04 PM 2023/4/27
	 * @Param: [projectInfoVO]
	 * @return: void
	 **/
	private void setVO(ProjectInfoVO projectInfoVO){
		Optional.ofNullable(projectInfoVO.getProjectStatus()).ifPresent(m ->{
			switch (m){
				case 1:projectInfoVO.setProjectStatusName("续建");break;
				case 2:projectInfoVO.setProjectStatusName("新建");break;
				case 3:projectInfoVO.setProjectStatusName("谋划");break;
				default:break;
			}
		});
		Optional.ofNullable(projectInfoVO.getInvestmentCategory()).ifPresent(m ->{
			switch (m){
				case 1:projectInfoVO.setInvestmentCategoryName("股权投资");break;
				case 2:projectInfoVO.setInvestmentCategoryName("资产投资");break;
				default:break;
			}
		});
		Optional.ofNullable(projectInfoVO.getProjectCategory()).ifPresent(m ->{
			switch (m){
				case 1:projectInfoVO.setProjectCategoryName("自营项目（主业项目)");break;
				case 2:projectInfoVO.setProjectCategoryName("自营项目（培育业务项目）");break;
				case 3:projectInfoVO.setProjectCategoryName("自营项目（非主业项目）");break;
				case 4:projectInfoVO.setProjectCategoryName("政府性项目");break;
				default:break;
			}
		});
		Optional.ofNullable(projectInfoVO.getNegativeType()).ifPresent(m ->{
			switch (m){
				case 1:projectInfoVO.setNegativeTypeName("监管类");break;
				case 2:projectInfoVO.setNegativeTypeName("禁止类");break;
				default:break;
			}
		});

		Optional.ofNullable(projectInfoVO.getInvestmentRegion()).ifPresent(m ->{
			switch (m){
				case 1:projectInfoVO.setInvestmentRegionName("境内");break;
				case 2:projectInfoVO.setInvestmentRegionName("境外");break;
				default:break;
			}
		});
		Optional.ofNullable(projectInfoVO.getIsCooperation()).ifPresent(m ->{
			switch (m){
				case "1":projectInfoVO.setIsCooperationName("央企");break;
				case "2":projectInfoVO.setIsCooperationName("省企");break;
				case "3":projectInfoVO.setIsCooperationName("宁波市国企");break;
				case "4":projectInfoVO.setIsCooperationName("否");break;
				default:break;
			}
		});
	}

	/**
	 * 下发处室消息
	 *
	 * @param projectInfo
	 * @return void
	 **/
	public void sendMessage(ProjectInfo projectInfo) {
		List<Message> messages = new ArrayList<>();
		//当前登陆用户
		String userId = TokenUtil.getTokenUserId();
		String orgName = projectInfo.getInvestmentCompanyId();
		try {
			PageData findbyid = userDao.findbyid(userId);
			String name = findbyid.getString("name");
			Office office = officeService.getOne(new LambdaQueryWrapper<Office>().eq(Office::getName, "规划处"));
			if (Optional.ofNullable(office).isPresent()){
				//下发处室的人
				List<PageData> userByOffice = userDao.getUserByOffice(office.getId());

				if (CollectionUtil.isNotEmpty(userByOffice)) {
					for (PageData pageData : userByOffice) {
						Message message = Message.builder().formId(projectInfo.getId() + "").orgName(orgName)
								.orgId(gzwProperties.getId()).formType(projectInfo.getFormType()).formTypeName("投资项目调整").messageTime(DateUtil.now())
								.createUser(pageData.getString("id")).message("【" + projectInfo.getProjectName()+ "】项目内容修改！").sendUser(userId).sendUserName(name).isIgnore(0).build();

						messages.add(message);
					}
				}
			}
			messageService.saveBatch(messages);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public ProjectInfoVO getDetailVO(Object id) {
		return projectInfosWrapper.entityToVO(getById(Long.valueOf(String.valueOf(id))));
	}
	@Override
	public String export(String lastYear,String superviseFlag){
		String key = System.currentTimeMillis() + StringPool.DASH + UUID.randomUUID().toString().replace(StringPool.DASH, "");
		String fileName = key + ".xlsx";
		String exportPath = environment.getProperty("excel.path");
		/**
		 * 导出路径不存在则创建
		 */
		File file = new File(exportPath);
		if (!file.exists()) {
			file.mkdirs();
		}
		InputStream inputStream = this.getClass().getResourceAsStream("/exceldemo/projectInfoExportNew1.xlsx");
		ExcelWriter excelWriter = EasyExcel.write(exportPath + fileName).withTemplate(inputStream).build();
		FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();

		WriteSheet staffFilesWriteSheet = EasyExcel.writerSheet(0).build();
		QueryWrapper<ProjectInfo> queryWrapper = new QueryWrapper<>();
		this.addTokenQueryAudit(queryWrapper);
		queryWrapper.eq("investment_category",2);
		queryWrapper.eq(StringUtils.isNotBlank(lastYear),"last_year",lastYear);
		queryWrapper.orderByDesc("is_main_business");
		List<ProjectInfo> projectInfos=projectInfoMapper.selectList(queryWrapper);
		List<ProjectInfoVO> projectInfoVOS = projectInfosWrapper.entityToVO(projectInfos);
		if(projectInfoVOS!=null&&projectInfoVOS.size()>0){
			getVos(projectInfoVOS);
		}

		// 其他参数可以使用Map封装
		Map<String, Object> otherMap = new HashMap<>(16);
		otherMap.put("lastYear", lastYear);


		excelWriter.fill(projectInfoVOS, fillConfig, staffFilesWriteSheet);

		excelWriter.fill(otherMap,staffFilesWriteSheet);
		WriteSheet staffFilesWriteSheetTwo = EasyExcel.writerSheet(1).build();
		QueryWrapper<ProjectInfo> queryWrapperTwo = new QueryWrapper<>();
		this.addTokenQueryAudit(queryWrapperTwo);
		queryWrapperTwo.eq("investment_category",1);
		queryWrapperTwo.eq(StringUtils.isNotBlank(lastYear),"last_year",lastYear);
		queryWrapper.orderByDesc("is_main_business");
		List<ProjectInfo> projectInfosTwo=projectInfoMapper.selectList(queryWrapperTwo);
		List<ProjectInfoVO> projectInfoVOSTwo = projectInfosWrapper.entityToVO(projectInfosTwo);
		if(projectInfoVOSTwo!=null&&projectInfoVOSTwo.size()>0){
			getVos(projectInfoVOSTwo);
		}
		excelWriter.fill(projectInfoVOSTwo,fillConfig, staffFilesWriteSheetTwo);

		excelWriter.fill(otherMap,staffFilesWriteSheetTwo);





		excelWriter.finish();
		PageData org = orgzationService.getCompanyNameById(TokenUtil.getTokenOrgId());
		String companyName = "";
		if (org != null) {
			companyName = org.getString("name");
		}
		String lastName;
		if("2".equals(superviseFlag)){
			lastName = "_特别监管类项目";
		}else {
			lastName = "_项目投资库";
		}
		String excelName = companyName + lastName;
		fileNameMap.put(key, excelName);
		return key;
	}
	public void getVos(List<ProjectInfoVO> projectInfoVOS){
		Integer countNum=0;
		for (ProjectInfoVO projectInfoVO: projectInfoVOS) {
			if(projectInfoVO!=null){
				countNum=countNum+1;
				projectInfoVO.setCountNum(countNum);
				if(projectInfoVO.getPlanFinishDate()!=null){

				}
				if(projectInfoVO.getInvestmentCategory()!=null){
					if(projectInfoVO.getInvestmentCategory()==1){
						projectInfoVO.setInvestmentCategoryName("股权投资");
					}else if(projectInfoVO.getInvestmentCategory()==2){
						projectInfoVO.setInvestmentCategoryName("固定资产投资");
					}else if(projectInfoVO.getInvestmentCategory()==3){
						projectInfoVO.setInvestmentCategoryName("无形资产投资");
					}else if(projectInfoVO.getInvestmentCategory()==4){
						projectInfoVO.setInvestmentCategoryName("金融投资");
					}
				}
				//项目属性
				if(projectInfoVO.getProjectCategory()!=null){
					if(projectInfoVO.getProjectCategory()==1){
						projectInfoVO.setProjectCategoryName("自营项目（主业项目)");
					}else if(projectInfoVO.getProjectCategory()==2){
						projectInfoVO.setProjectCategoryName("自营项目（培育业务项目）");
					}else if(projectInfoVO.getProjectCategory()==3){
						projectInfoVO.setProjectCategoryName("自营项目（非主业项目）");
					}else if(projectInfoVO.getProjectCategory()==4){
						projectInfoVO.setProjectCategoryName("政府性项目");
					}
				}
				//项目状态
				if(projectInfoVO.getProjectStatus()!=null){
					if(projectInfoVO.getProjectStatus()==1){
						projectInfoVO.setProjectStatusName("续建");
					}else if(projectInfoVO.getProjectStatus()==2){
						projectInfoVO.setProjectStatusName("新建");
					}else if(projectInfoVO.getProjectStatus()==3){
						projectInfoVO.setProjectStatusName("已完工");
					}
				}
				//负面类型
				if(projectInfoVO.getNegativeType()!=null){
					if(projectInfoVO.getNegativeType()==1){
						projectInfoVO.setNegativeTypeName("监管类");
					}else if(projectInfoVO.getNegativeType()==2){
						projectInfoVO.setNegativeTypeName("禁止类");
					}
				}
				//投资属性
				if(projectInfoVO.getInvestmentAttribute()!=null){
					if(projectInfoVO.getInvestmentAttribute()==1){
						projectInfoVO.setInvestmentAttributeName("主业");
					}else if(projectInfoVO.getInvestmentAttribute()==2){
						projectInfoVO.setInvestmentAttributeName("非主业");
					}
				}
				//选择投资属性为主业之后选择  投资属性主业详情主业：1核心主业 2培育主业
				if(projectInfoVO.getInvestmentAttributeItem()!=null){
					if(projectInfoVO.getInvestmentAttributeItem()==1){
						projectInfoVO.setInvestmentAttributeItemName("核心主业");
					}else if(projectInfoVO.getInvestmentAttributeItem()==2){
						projectInfoVO.setInvestmentAttributeItemName("培育主业");
					}
				}
				//投资地域
				if(projectInfoVO.getInvestmentRegion()!=null){
					if(projectInfoVO.getInvestmentRegion()==1){
						projectInfoVO.setInvestmentRegionName("境内");
						projectInfoVO.setInvestmentRegionJN("是");
						projectInfoVO.setInvestmentRegionJW("否");
					}else if(projectInfoVO.getInvestmentRegion()==2){
						projectInfoVO.setInvestmentRegionName("境外");
						projectInfoVO.setInvestmentRegionJW("是");
						projectInfoVO.setInvestmentRegionJN("否");
					}
				}
				if(projectInfoVO.getIsLocal()!=null){
					if(projectInfoVO.getIsLocal()==1){
						projectInfoVO.setIsLocalSW("是");
						projectInfoVO.setIsLocalSN("否");
					}else if(projectInfoVO.getIsLocal()==2){
						projectInfoVO.setIsLocalSN("是");
						projectInfoVO.setIsLocalSW("否");
					}
				}

				//是否与其他国资合作:1央企 2省企 3宁波市国企 4否
				if(projectInfoVO.getIsCooperation()!=null){
					if(projectInfoVO.getIsCooperation().equals("1")){
						projectInfoVO.setIsCooperationName("央企");
					}else if(projectInfoVO.getIsCooperation().equals("2")){
						projectInfoVO.setIsCooperationName("省企");
					}else if(projectInfoVO.getIsCooperation().equals("3")){
						projectInfoVO.setIsCooperationName("邢台市国企");
					}else if(projectInfoVO.getIsCooperation().equals("4")){
						projectInfoVO.setIsCooperationName("否");
					}
				}
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
				if(projectInfoVO.getAnticipateStartTime()!=null){
					projectInfoVO.setAnticipateStartTimeStr(sdf.format(projectInfoVO.getAnticipateStartTime()));
				}
				if(projectInfoVO.getPlanFinishDate()!=null){
					projectInfoVO.setPlanFinishDateStr(sdf.format(projectInfoVO.getPlanFinishDate()));
				}
			}
		}
	}
	/**
	 * 根据flag 判断是否过滤登录信息 1本级所有数据和下级通过审批数据 2本级所有数据
	 *
	 * @param wrapper
	 * @param
	 * @return
	 */
	public void addTokenQueryAudit(QueryWrapper<ProjectInfo> wrapper){
		String orgId = TokenUtil.getTokenOrgId();

		IOrgService orgService = SpringUtil.getBean(IOrgService.class);
		GzwProperties gzwProperties = SpringUtil.getBean(GzwProperties.class);
		String gzwOrgId = gzwProperties.getId();
		if (orgId.equals(gzwOrgId)){
			//国资节点
			wrapper.lambda().and(andWrapper ->
					andWrapper.eq(ProjectInfo::getStatus, FormStatusConstant.FINISH).or()
							.eq(ProjectInfo::getCreateCompanyId, orgId)
			);
		}else{
			List<String> allChildIds = orgService.getAllChildIds(orgId);
			wrapper.lambda().and(andWrapper ->
					andWrapper.in(ProjectInfo::getCreateCompanyId, allChildIds)
							.eq(ProjectInfo::getStatus, FormStatusConstant.FINISH).or()
							.eq(ProjectInfo::getCreateCompanyId, orgId) );
		}

	}
	@Override
	public void download(String key, HttpServletResponse response) {
		if (!fileNameMap.containsKey(key)) {
			log.error("BaseInvestmentPlanServiceImpl 导出excel失败--------> key " + key);
			return;
		}
		String excelName = fileNameMap.get(key);
		String excelPath = environment.getProperty("excel.path") + "/" + key + ".xlsx";
		FileTools.exportExcel(excelPath, excelName, response);
		fileNameMap.remove(key);
	}
}
